import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Response } from 'express';
import { map, Observable } from 'rxjs';

/* 
@Get()
getHello(){
  return 'abc'  
}

在 Nest.js 中，所有的路由处理器都会被自动包装在管道中。这个管道会在路由处理器执行之前和之后分别执行一些操作，例如验证请求参数、记录请求日志、处理异常等等。
对于上面的代码片段，getHello() 方法也会被自动包装在管道中。

具体来说，Nest.js 会在 getHello() 方法执行之前和之后执行一些默认的管道操作，例如记录请求日志和处理异常。
如果需要自定义管道操作，可以通过创建自定义管道类来实现。
需要注意的是，如果在路由处理器中使用了 @UsePipes() 装饰器，那么这个装饰器指定的管道类也会被自动包装在默认管道中。这样可以保证自定义管道和默认管道都能够正常工作。


在 Nest.js 中，管道程序返回的 Observable 会传递给下一个中间件或者路由处理器。
具体来说，当管道程序返回一个 Observable 时，Nest.js 会等待这个 Observable 完成，
然后将其结果传递给下一个中间件或者路由处理器。

如果最后没有中间件或者路由处理器了，
Nest.js 会将管道程序返回的 Observable 的结果传递给 HTTP 响应。具体来说，
Nest.js 会将 Observable 的结果转换为一个 HTTP 响应，然后发送给客户端。
*/




//这是一个全局响应拦截器,可以在main.ts中设置
@Injectable()
export class FormatResponseInterceptor implements NestInterceptor {

  // constructor(private appService : AppService){}
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const response = context.switchToHttp().getResponse<Response>();

    /* 
      当我们使用 next.handle() 方法调用请求管道中的下一个处理程序。
      返回Observable对象(执行结果)，会传递给pipe()函数，做进一步处理。
      
      可以使用 pipe 方法来对这个 Observable 对象 添加操作符。
      map操作符 用于对 observable 中的每个元素进行转换，返回一个新的 observable，
      tap操作符 允许我们在 Observable 对象的流中添加一个副作用操作，而不会改变流的内容。

      在 NestJS 中，这些方法通常用于拦截器、中间件和其他请求管道组件中，
      以对请求进行处理、转换和监视 
    */

    return next.handle().pipe(map((data) => {
      return {
        code: response.statusCode,
        message: 'success',
        data
      }
    }));

  }
}

